﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IdeaNMR.Web.Core
{
    [Serializable]
    public class PulseProgramFacade : NMRObjectFassade<PulseProgram>
    {
        public void AttachExperiment(Experiment exp, Spectrometer spec, Sample samp)
        {
            Spectrometer sP = this.Inmr.BaseObjects.OfType<Spectrometer>().Where(ss => ss.Id == spec.Id).Single();
            Sample sA = this.Inmr.BaseObjects.OfType<Sample>().Where(ss => ss.Id == samp.Id).Single();

            User u = this.User;

            exp.Spectrometer = sP;
            exp.Sample = sA;
            exp.User = u;
            this.Content.Experiments.Add(exp);
            this.Inmr.SaveChanges();
        }

        protected override PulseProgram GetContent()
        {
            PulseProgram result = base.GetContent();

            if (this.Content != null)
            {
                if (!this.Content.AuxComponents.IsLoaded) this.Content.AuxComponents.Load();

                foreach (NamedComponent nC in this.Content.AuxComponents)
                {
                    if (!nC.AuxComponentReference.IsLoaded) nC.AuxComponentReference.Load();

                    if (!nC.AuxComponent.Authors.IsLoaded)
                        nC.AuxComponent.Authors.Load();
                    if (nC.AuxComponent.IsPrivate && nC.AuxComponent.Authors.All(
                        aa =>
                        {
                            if (!aa.UserReference.IsLoaded) aa.UserReference.Load();
                            return aa.User.Username != ScrewTurnWikiFacade.Username;
                        }
                        )) continue;

                    AuxComponent aucCopy;
                    EntityType eT = nC.AuxComponent.GetEntityType();
                    switch (eT)
                    {
                        case EntityType.WaveShape:
                            aucCopy = new Wave();
                            break;
                        case EntityType.Cpd:
                            aucCopy = new Cpd();
                            break;
                        case EntityType.Script:
                            aucCopy = new Script();
                            break;
                        default:
                            string msg = string.Format("PulseProgramFacade is not designed to accept AuxComponent of type {0}.", eT.ToString());
                            throw new NotImplementedException(msg);
                    }

                    nC.AuxComponent.CopyTo(aucCopy, true);

                    NamedComponent nCcopy = new NamedComponent();
                    nCcopy.AuxComponent = aucCopy;
                    nCcopy.Id = Guid.NewGuid();
                    nCcopy.Identifier = nC.Identifier;
                    result.AuxComponents.Add(nCcopy);

                    NamedComponent n = new NamedComponent();
                }
            }

            return result;
        }

        protected override void CreateRelationships(PulseProgram obj, SaveModeOptions smo)
        {
            base.CreateRelationships(obj, smo);

            foreach (var auc in obj.AuxComponents.ToArray())
                this.Inmr.DeleteObject(auc);

            obj.AuxComponents.Clear();
            bool isPublic = !obj.IsPrivate;

            foreach (NamedComponent nC in this.EntityObject.AuxComponents)
            {
                NamedComponent n = new NamedComponent();
                n.Id = Guid.NewGuid();
                n.Identifier = nC.Identifier;
                n.AuxComponent = this.Inmr.BaseObjects.OfType<AuxComponent>().Where(bo => bo.Id == nC.AuxComponent.Id).FirstOrDefault();
                if (isPublic) n.AuxComponent.IsPrivate = false;

                obj.AuxComponents.Add(n);
            }
        }

        public PulseProgramFacade(string username)
            : base(username)
        { }
        public PulseProgramFacade(Guid targetID, string username)
            : base(targetID, username)
        { }
    }
}
